package cn.tedu.blog.server.service.impl;

import cn.tedu.blog.server.exception.ServiceException;


import cn.tedu.blog.server.mapper.ArticleMapper;
import cn.tedu.blog.server.mapper.ArticleTagMapper;
import cn.tedu.blog.server.mapper.CategoryMapper;
import cn.tedu.blog.server.mapper.TagMapper;
import cn.tedu.blog.server.pojo.dto.ArticleAddNewDTO;
import cn.tedu.blog.server.pojo.dto.ArticleEditDTO;
import cn.tedu.blog.server.pojo.entity.Article;
import cn.tedu.blog.server.pojo.vo.ApiArticleListItemVO;
import cn.tedu.blog.server.pojo.vo.ArticleAdminDetailVO;
import cn.tedu.blog.server.pojo.vo.ArticleDetailVO;
import cn.tedu.blog.server.pojo.vo.ArticleListItemVO;
import cn.tedu.blog.server.service.IArticleService;
import cn.tedu.blog.server.utils.JsonPage;
import cn.tedu.blog.server.utils.OssUtils;
import cn.tedu.blog.server.utils.ServiceCode;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class ArticleServiceImpl implements IArticleService {
    @Autowired
    ArticleMapper articleMapper;
    @Autowired
    CategoryMapper categoryMapper;
    @Autowired
    ArticleTagMapper articleTagMapper;
    @Autowired
    TagMapper tagMapper;
    @Override
    public void addNew(ArticleAddNewDTO addNewDTO) {
        log.debug("即将执行articleService的逻辑：{}",addNewDTO);

        if(articleMapper.getByTitle(addNewDTO.getTitle())!=null){
            String message = "添加文章失败，文章"+addNewDTO.getTitle()+"已存在";
           throw  new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        Article article = new Article();
        BeanUtils.copyProperties(addNewDTO,article);
        LocalDateTime createTime = LocalDateTime.now();
        article.setGmtCreate(createTime);
        article.setGmtCreatePush(createTime);
        article.setGmtModified(createTime);
        article.setSort(0);
        article.setViewCount(0L);
        article.setPraiseCount(0L);
        article.setFavorCount(0L);
        article.setCommentCount(0L);
        Long categoryId = categoryMapper.selectIdByName(addNewDTO.getCategory());

        article.setCategoryId(categoryId);


//        article.setContent(MarkdownUtils.markdownToHtml(addNewDTO.getContent()));


       int rows = articleMapper.insert(article);
        if(rows!=1){
            String message ="添文章失败，系统繁忙，错误码【1】，请稍后再试";
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }
        List<Long> tagIds=tagMapper.selectIdByName(addNewDTO.getTags());
        rows=articleTagMapper.insert(article.getId(),tagIds,createTime);
        if(rows<1){
            String message ="添文章标签关联失败，系统繁忙，错误码【2】，请稍后再试";
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }
        /*根据分类数量*/

         rows= categoryMapper.updateArticleCountById(article.getCategoryId(), 1L);
        if(rows<1){
            String message ="修改分类文章数量失败，错误码【3】，请稍后再试";
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }

    }

    @Override
    public int selectCount() {
        int count =articleMapper.selectCount();
        return count;
    }
    

    @Override
    public void deleteById(long id) {
        log.debug("开始处理删除文章业务, 接收到的参数id={}", id);
        // 先查询文章是否存在, 如果不存在, 则抛出异常
        ArticleDetailVO articleDetailVO = articleMapper.getById(id);
        if (articleDetailVO == null) {
            String message = "删除文章失败,尝试删除的数据(id= " + id + ")不存在! ";
            log.error(message);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }
        /*根据分类数量*/
        int  rows= categoryMapper.updateArticleCountById(articleDetailVO.getCategoryId(), -1L);
        if(rows<1){
            String message ="修改分类文章数量失败，请稍后再试";
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }

        /*删除oss文章图片*/
        String url =articleDetailVO.getViewPicture();
        OssUtils.delete(url);
        // 代码走到这里说明文章存在, 则执行删除
         rows = articleMapper.deleteById(id);
        // 如果执行删除返回的受影响行数不等于1, 则抛出异常
        if (rows != 1) {
            String message = "删除文章失败,服务器忙,请稍后再试!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERR_UNKNOWN, message);
        }

    }
        /*批量删除文章*/
    @Override
    public int  deleteByIds(Long [] ids) {
        List<ArticleDetailVO> list =articleMapper.selectByIds(ids);
        for (ArticleDetailVO articleDetailVO:list) {

            String url =articleDetailVO.getViewPicture();
            OssUtils.delete(url);
            /*根据分类数量*/
            int rows= categoryMapper.updateArticleCountById(articleDetailVO.getCategoryId(), -1L);
            if(rows< 1){
                String message ="修改分类文章数量失败，请稍后再试";
                throw new ServiceException(ServiceCode.ERR_INSERT,message);
            }
        }
        log.debug("开始处理根据多个id批量删除文章业务, 接收到的参数id={}", ids);
        int rows = articleMapper.deleteByIds(ids);

        return rows;
    }

    @Override
    public void update(long id, ArticleEditDTO articleEditDTO) {
        log.debug("开始处理根据id修改文章的业务, 接收到的参数:{}", articleEditDTO);
        // 先查文章是否存在, 不存在抛出异常
        ArticleDetailVO articleDetailVO = articleMapper.getById(id);
        if (articleDetailVO == null) {
            String message = "修改文章失败, 尝试修改的文章(id= " + id + ")不存在!";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        // 代码走到这里说明文章存在
        Article article = new Article();
        BeanUtils.copyProperties(articleEditDTO, article);
        //补全属性
        article.setId(id);
        LocalDateTime modified = LocalDateTime.now();
        article.setGmtModified(modified);
        log.debug("article:{}", article);
        int rows = articleMapper.updateById(article);
        // 如果返回的受影响行数不等于1, 抛出异常
        if (rows != 1) {
            String message = "修改文章数据失败, 服务器忙, 请稍后再试";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }
    
    @Override
    public ArticleDetailVO adminSelect(Long id) {
        log.debug("===正在执行查询ArticleService后台文章列表查询====");
        ArticleDetailVO articleDetailVO =articleMapper.adminSelect(id);
        log.debug("查询列表结果为：{}",articleDetailVO.toString());
        return articleDetailVO;
    }
    @Override
    public List<ArticleAdminDetailVO> adminSelectFindAll(ArticleAdminDetailVO articleAdminDetailVO) {
        log.debug("===正在执行查询ArticleService后台文章列表查询===={},{}",articleAdminDetailVO.toString());
        List<ArticleAdminDetailVO> list =articleMapper.adminSelectFindAll(articleAdminDetailVO);
        log.debug("分页查询所有文章列表{}",list);
        return list;
    }
    
    /*  ------前台部分---------   */
    @Override
    public JsonPage<ApiArticleListItemVO> listArticlesByCategoryId(Long categoryId, Integer page, Integer pageSize) {
        PageHelper.startPage(page, pageSize);
        List<ApiArticleListItemVO> apiArticleListItemVOs = articleMapper.listArticlesByCategoryId(categoryId);
        return JsonPage.restPage(new PageInfo<>(apiArticleListItemVOs));
    }
}
